#!/usr/bin/python3
# -*- coding: UTF-8 -*- 
# 设置utf-8  显示中文
"""
@Create Time: 2021/1/14 下午3:31
@Author: guo
@File：handle_request_data.py
"""
import ast
import json
from string import Template

from config.get_conf_data import GetConfData
from common.yml.get_yml_keys import GetYmlKeys


class HandleRequestData:

    """"""
    def __init__(self):
        self.__conf = GetConfData()

    def get_request_data(self,page_api_data:dict,yml_keys:GetYmlKeys,case_api_data:dict=None,req_keys:list=None)->dict:
        """
        获取请求数据等,这里有host,url 等.需要注意的是: host ,url,post 是在page层,case层没有这些数据. \n
        :param page_api_data: 对应的page层的yml里的 api_data 的数据
        :param yml_keys: yml的keys
        :param case_api_data: 传入的case层 yml数据 对应的 api_data的数据
        :param req_keys: 传入的case层的yml数据 对应的key
        :return: dict(request_data)
        """
        api_data = page_api_data
        yml_keys = yml_keys
        req_params = case_api_data
        req_keys = req_keys

        # 先获取相应的host、path，并进行拼接相应的url
        path_key = yml_keys.get_path_key()
        host_key = yml_keys.get_host_key()
        path_value = api_data[path_key]
        host_value = api_data[host_key]
        # config.yml里的值
        unify_host = self.__conf.get_unify_host()
        # config.yml里的值
        host = self.__conf.get_host()

        # 判断是使用config里的host 还是 每个case自己的host
        if unify_host == True:
            host_value = host

        url_key = yml_keys.get_url_key()
        url_value = host_value + path_value

        url = {}
        url[url_key] = url_value

        # 获取业务/page层的yml文件中的 request data数据。
        request_data_key = yml_keys.get_request_data_key()
        request_data = api_data[request_data_key]

        # 想要获取request_data里的data数据，就得先获取 request_data的data类型。
        data_type_key = yml_keys.get_data_type_key()
        data_type = api_data[data_type_key]
        # 获取case数据层request_data的data数据
        data = req_params[request_data_key][data_type]
        # # 下面注释的代码被废弃掉了,不使用.因为在使用模板替换技术的时候,会将None值给替换为'None',变成了一个字符串值.
        # if data == None:
        #     # 进行数据的替换。
        #     request_data_template = Template(json.dumps(request_data))
        #     # 使用模板替换技术，进行数据的替换，此时只需要替换url
        #     request_data_tmp = request_data_template.substitute(**url)
        # else:
        #     # 在进行使用模板替换技术之前,要先检测request_data里的key的值是否有"."的情况,如actionType.id
        #     # 当出现这种情况时,就不能使用模板替换技术.要直接先进行赋值
        #
        #     page_keys = request_data.keys()
        #     case_keys = data.keys()
        #     for item in case_keys:
        #         """理论上讲,case层的key的值,都是需要与对应page层的key的值 进行的替换的.
        #         所以在这里只需要检测case层的key即可.也就说case层的key,在对应的page层对应的key,都会是变量.
        #         所以只需要拿case层的key进行检测即可,也不需要再进行判断startWith('${')等."""
        #         if "." in item:
        #             request_data[data_type][item] = data[item]
        #
        #     # 进行数据的替换。
        #     request_data_template = Template(json.dumps(request_data))
        #     # 要替换url和 request_data 里的data
        #     request_data_tmp = request_data_template.substitute(**url, **data)

        # 使用for循环进行数据替换.
        if data != None:
            case_keys = data.keys()
            for item in case_keys:
                request_data[data_type][item] = data[item]

        """由于request_data中的data部分会存在着数据依赖，也就是说data中的key对应的value，有可能为变量，如：
        data:{'userId':'${userId}'} 当出现这种情况时，执行下面的代码时，会就提示 keyerror错。
        所以为了避免这种情况，对url的替换时，将不再使用模板替换技术。"""
        # # 进行数据的替换。
        # request_data_template = Template(json.dumps(request_data))
        # # 使用模板替换技术，进行数据的替换，此时只需要替换url
        # request_data_tmp = request_data_template.substitute(**url)
        #
        # # 重新赋值
        # api_data[request_data_key] = json.loads(request_data_tmp)
        # data = api_data[request_data_key][data_type]

        # 直接对url的值进行替换
        request_data[url_key] = url_value
        data = request_data[data_type]

        # 将list类型的str，转化为list
        request_data[data_type]=self.__str_to_list(data)
        return request_data


    def __str_to_list(self, request_data: dict) -> dict:
        """
        处理request_data里的data数据，因为在data数据里存在类似于"username": "['zhangsan', 'lisi']"，此时的username的值为str
        而这种数据实际上应该为："username":['zhangsan','lisi']，此时的username的值为list
        所以需要将list类型的str转化为list。此时要使用到eval() 或 ast.literal_eval().而ast.literal_eval()要比eval()安全
        """
        data = request_data
        if isinstance(data, dict):
            for key, item in data.items():
                # 必须要先判断item的值是否为None，因为存在None的情况。
                if item != None:
                    # 防止出现 item 为int的情况,此时如果不加类型判断,就会报错.
                    if isinstance(item, str):
                        if item.startswith("[") and item.endswith("]"):
                            # eval() 与 ast.literal_eval()相比，不安全。所以推荐使用 as.literal_eval()
                            # data[key] = eval(item)
                            data[key] = ast.literal_eval(item)

        return data

